﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Helpers.Enums
{
    public class EnumHelper
    {
        public static string GetDescription<T>(int value)
        {
            Enum enumValue = (Enum)Enum.ToObject(typeof(T), value);
            return GetDescription(enumValue);
        }

        public static T GetAttribute<T>(Enum value) where T : Attribute
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            string description = value.ToString();
            FieldInfo fieldInfo = value.GetType().GetField(description);
            if (fieldInfo == null)
                return null;

            object[] attrs = fieldInfo.GetCustomAttributes(typeof(T), false);
            if (attrs == null || attrs.Length < 1)
                return null;

            foreach (object attr in attrs)
                if (attr.GetType() == typeof(T))
                    return (T)attr;

            return null;
        }

        public static string GetDescription(Enum value)
        {
            EnumDescriptionAttribute attr = GetAttribute<EnumDescriptionAttribute>(value);
            string description = (attr == null || attr.Description == null)
                                    ? value.ToString() : attr.Description;

            return description;
        }

        public static Enum GetDefaultValue(Type enumType)
        {
            foreach (Enum value in Enum.GetValues(enumType))
            {
                if (GetAttribute<EnumDefaultValueAttribute>(value) != null)
                    return value;
            }
            return (Enum)Enum.GetValues(enumType).GetValue(0);
        }

        public static T ResolveValueByName<T>(string name)
            where T : struct
        {
            T? result = null;

            if (name != null && name.Trim().Length > 0)
            {
                foreach (var eValue in Enum.GetValues(typeof(T)))
                {
                    string eName = Enum.GetName(typeof(T), eValue);
                    if (eName.ToUpper() == name.Trim().ToUpper())
                    {
                        result = (T)eValue;
                        break;
                    }
                }
            }

            if (!result.HasValue)
                throw new Exception(String.Format("Name '{0}' can not be resolved for enum '{1}'", name, typeof(T).Name));

            return result.Value;
        }
    }
}
